package sk.uniba.fmph.asdf.test;

import java.util.Objects;
import sk.uniba.fmph.asdf.tempt.PrimaryTestFieldDef;
import sk.uniba.fmph.asdf.tempt.TestFieldDef;

/**
 * Trieda predstavujuca pole opravovaneho testu.
 *
 * @author Matej
 * @author tim
 * @author Ivor
 * @serial
 */
public class PrimaryTestField extends TestField {
	private static final long serialVersionUID = 9090316579677292679L;

	/**
	 * specifikacia vlastnosti pola podla sablony
	 *
	 * @serialField
	 */
	private PrimaryTestFieldDef testFieldDef;

	/**
	 * rozsirenie spola
	 *
	 * @serialField
	 */
	private TestFieldDef fieldExtension;

	@Override
	public void validateState() {
		testFieldDef.validateState();
		fieldExtension.validateState();
	}

	/**
	 * Vytvori novu instanciu objektu podla zadanej definicie oblasti.
	 *
	 * @param fieldDefinition
	 *            Definicia oblasti.
	 */
	public PrimaryTestField(PrimaryTestFieldDef fieldDefinition) {
		this.testFieldDef = fieldDefinition;
	}

	public void addFieldExtension(TestFieldDef fieldExtension) {
		addFieldExtension(fieldExtension.getTopLeft(),
				fieldExtension.getBottomRight());
	}

	public void addFieldExtension(RelativePoint topLeft,
			RelativePoint bottomRight) {
		fieldExtension = new TestFieldDef(0/* WTF id */, topLeft, bottomRight);
	}

	/**
	 * Zmeni hranice pola.
	 *
	 * @param topLeft
	 *            horny lavy okraj
	 * @param bottomRight
	 *            pravy dolny okraj
	 */
	public void editFieldExtension(RelativePoint topLeft,
			RelativePoint bottomRight) {
		fieldExtension.setTopLeft(topLeft);
		fieldExtension.setBottomRight(bottomRight);
	}

	public void deleteFieldExtension() {
		/* TODO */
		fieldExtension = null;
	}

	/**
	 * Zisti, ci je mozne pridat peciatku do pola. V pripade ze ano zavola
	 * rodicovsku metodu.
	 *
	 * @see sk.uniba.fmph.asdf.test.TestField#addStamp(int, int,
	 *      sk.uniba.fmph.asdf.test.StampType)
	 */
	@Override
	public boolean addStamp(float x, float y, StampType type) {
		if (type == StampType.CORRECT || type == StampType.ALTERNATIVE_ANSWER
				|| type == StampType.EXTENSION) {
			int count = 0;
			for (Stamp s : stamps) {
				if ((s.getStampType() == StampType.EXTENSION && type == StampType.EXTENSION)
						|| (type != StampType.EXTENSION && s.getStampType().isEvaluating())) {
					count++;
				}
			}
			if ((type == StampType.EXTENSION && count >= 1)
					|| ((type == StampType.CORRECT || type == StampType.ALTERNATIVE_ANSWER)
							&& count >= testFieldDef.getMaxPoints())) {
				return false;
			}
		}
		return super.addStamp(x, y, type);
	}

	@Override
	public void addComment(float x, float y, String value) {
		super.addComment(x, y, value);
	}

	@Override
	public int getEvaluation() {
		return super.getEvaluation();
	}

	public PrimaryTestFieldDef getTestFieldDef() {
		return testFieldDef;
	}

	public TestFieldDef getFieldExtension() {
		return fieldExtension;
	}

	@Override
	public boolean equals(Object obj) {
		PrimaryTestField other = (PrimaryTestField) obj;
		return testFieldDef.equals(other.testFieldDef);
	}

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 67 * hash + Objects.hashCode(this.testFieldDef);
        return hash;
    }
}
